from __future__ import with_statement

import os
from contextlib import closing

def nosound():
    pass

def use_winsound(soundfile):
    try:
        import winsound
    except ImportError:
        return nosound
    return lambda: winsound.PlaySound(soundfile, winsound.SND_ASYNC)

def use_nssound(soundfile):
    try:
        from AppKit import NSSound
    except ImportError:
        return nosound
    def play():
        sound = NSSound.alloc()
        sound.initWithContentsOfFile_byReference_(soundfile, True)
        sound.play()
    return play


def use_ossaudiodev(soundfile):
    try:
        import wave
        import ossaudiodev
    except ImportError:
        return nosound

    with closing(wave.open(soundfile, 'rb')) as s:
        nc, sw, fr, nf, comptype, compname = s.getparams()
        data = s.readframes(nf)

    def play():
        try:
            with closing(ossaudiodev.open('/dev/dsp', 'w')) as dsp:
                dsp.setparameters(ossaudiodev.AFMT_S16_NE, nc, fr)
                dsp.write(data)
        except IOError:
            pass
    return play

def use_pyglet(soundfile):
    try:
        import pyglet
    except ImportError:
        return nosound

    media = pyglet.media.load(soundfile, streaming=False)
    player = pyglet.media.ManagedSoundPlayer()

    def play():
        player.queue(media)
        if player.playing:
            player.next()
        else:
            player.play()
    return play

def use_pygame(soundfile):
    try:
        import pygame
    except ImportError:
        return nosound
    pygame.init()
    return pygame.mixer.Sound(soundfile).play

def make_player(soundfile):
    for player in (use_winsound, use_nssound, use_pyglet, use_ossaudiodev, use_pygame):
        play = player(soundfile)
        if play is not nosound:
            return play
    return nosound

_QUACK = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'anec.wav')
def quack():
    return make_player(_QUACK)
